package com.study.service.db3.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.Page;
import com.study.entity.db3.Account;
import com.study.entity.db3.AccountRole;
import com.study.entity.db3.Role;
import com.study.entity.db3.dto.LoginDTO;
import com.study.entity.db3.qo.AccountQO;
import com.study.enumeration.DeletedEnum;
import com.study.mapper.db3.AccountMapper;
import com.study.mapper.db3.AccountRoleMapper;
import com.study.service.db3.IAccountService;
import com.study.util.BaseUtils;

import cn.hutool.crypto.digest.MD5;

/**
 * 账号表 服务实现类
 * 
 * @author chenk
 *
 */
@Service
public class AccountServiceImpl implements IAccountService {

	@Autowired
	private AccountMapper accountMapper;

	@Autowired
	private AccountRoleMapper accountRoleMapper;

	@Override
	public LoginDTO login(String username, String password) {
		LoginDTO loginDTO = new LoginDTO();
		loginDTO.setPath("redirect:/");

		// 根据用户名查询用户信息
		Account account = accountMapper.findAccountByLoginNameAndPassword(username, null);
		if (account == null) {
			loginDTO.setError("用户名不存在");
			return loginDTO;
		}

		// 对前台传过来的密码进行md5加盐加密，和后台查询出来的密码进行对比，如果不一致给出提示
		MD5 md5 = new MD5(account.getSalt().getBytes());
		String digestHex = md5.digestHex(password);
		if (!digestHex.equals(account.getPassword())) {
			loginDTO.setError("密码错误");
			return loginDTO;
		}

		loginDTO.setAccount(account);
		loginDTO.setPath("login/main");
		return loginDTO;
	}

	@Override
	public Page<Account> queryAccounts(Map<String, Object> requestParams) {
		// 前台参数转对象
		AccountQO account = BaseUtils.mapToEntity(requestParams, AccountQO.class);
		// 前台传来的时间范围做处理
		String createTimeRange = account.getCreateTimeRange();
		if (StringUtils.hasLength(createTimeRange)) {
			String[] timeArr = createTimeRange.split(" - ");
			account.setStartTime(timeArr[0]);
			account.setEndTime(timeArr[1]);
		}
		account.setDeleted(Integer.valueOf(DeletedEnum.否.getCode()));
		Page<Account> accounts = accountMapper.queryAccounts(account);
		List<Account> result = accounts.getResult();
		if (result != null && result.size() > 0) {
			for (Account a : result) {
				List<Role> roles = a.getRoles();
				if (roles != null && roles.size() > 0) {
					StringJoiner sj = new StringJoiner(",");
					for (Role r : roles) {
						sj.add(r.getRoleName());
					}
					a.setRoleNames(sj.toString());
				}
			}
		}
		return accounts;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveAccount(Account account) {
		accountMapper.saveAccount(account);

		String roleIds = account.getRoleIds();
		if (StringUtils.hasLength(roleIds)) {
			String[] roleIdArr = roleIds.split(",");
			for (String roleId : roleIdArr) {
				AccountRole accountRole = new AccountRole();
				accountRole.setAccountId(account.getAccountId());
				accountRole.setRoleId(Long.valueOf(roleId));
				accountRoleMapper.saveAccountRole(accountRole);
			}
		}

	}

	@Override
	public int countAccounts(String username, Long accountId) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("username", username);
		paramMap.put("accountId", accountId);
		paramMap.put("deleted", Integer.valueOf(DeletedEnum.否.getCode()));
		return accountMapper.countAccounts(paramMap);
	}

	@Override
	public Account getAccountById(Long id) {
		AccountQO account = new AccountQO();
		account.setAccountId(id);
		account.setDeleted(Integer.valueOf(DeletedEnum.否.getCode()));
		Account result = accountMapper.getAccountById(account);
		if (result != null) {
			List<Role> roles = result.getRoles();
			if (roles != null && roles.size() > 0) {
				StringJoiner sj = new StringJoiner(",");
				for (Role r : roles) {
					sj.add(r.getRoleName());
				}
				result.setRoleNames(sj.toString());
			}
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateAccount(Account account) {
		accountMapper.updateAccount(account);

		Long accountId = account.getAccountId();
		accountRoleMapper.deleteByAccountId(accountId);

		String roleIds = account.getRoleIds();
		if (StringUtils.hasLength(roleIds)) {
			String[] roleIdArr = roleIds.split(",");
			for (String roleId : roleIdArr) {
				AccountRole accountRole = new AccountRole();
				accountRole.setAccountId(accountId);
				accountRole.setRoleId(Long.valueOf(roleId));
				accountRoleMapper.saveAccountRole(accountRole);
			}
		}

	}

	@Override
	public void deleteById(Long id) {
		Map<String, Object> paramMap = new HashMap<>();
		// 逻辑删除标识(0、否 1、是)
		paramMap.put("deleted", "1");
		paramMap.put("accountId", id);
		accountMapper.deleteById(paramMap);
	}

}
